﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StoreTransport.DAO;
using StoreTransport.Data;
using StoreTransport.Business.Constants;
using StoreTransport.Business.Helper;

namespace StoreTransport.Business.Services {
    class Calculator {
        public static int ComputedNeedProduct(double saleRate, long currentQuantity, int numberSaleDys) {
            return Convert.ToInt32(saleRate * numberSaleDys - currentQuantity);
        }

        public static Dictionary<int, int> ComputeAllAmounts(List<MarketData> markets, int Package) {
            Dictionary<int, int> AllAmounts = new Dictionary<int, int>();
            foreach (MarketData market in markets) {
                foreach (int productKindId in market.DicProductKinds.Keys) {
                    int Amount = market.DicProductKinds[productKindId].ComputedStableProducts;
                    if (Amount > 0) {
                        if (!AllAmounts.ContainsKey(productKindId)) {
                            AllAmounts.Add(productKindId, 0);
                        }
                        AllAmounts[productKindId] += Amount;
                    }
                }
            }
            return AllAmounts;
        }

        /**
         * Transfer entity to dto to easily compute.
         * 
         * */
        public static List<MarketData> BuildMarketDto(List<MarketProductImport> markets, ProductLine pl, bool isAllocated,
            Dictionary<int, Dictionary<int, int>> marketTo, Dictionary<int, Dictionary<int, int>> marketFrom) {
            Dictionary<int, MarketData> cachedData = new Dictionary<int, MarketData>();
            foreach (MarketProductImport rr in markets) {
                string ProductKindName = CommonHelper.ProductKindList[rr.ProductKindId].ProductKindName;
                string ProductCode = CommonHelper.ProductList[rr.ProductId].ProductName;
                int MarketId = CommonHelper.MarketList[rr.MarketId].ID;
                MarketData dto = new MarketData();
                if (!cachedData.ContainsKey(MarketId)) {
                    dto.MarketName = CommonHelper.MarketList[rr.MarketId].MarketName;
                    dto.AreaName = CommonHelper.AreaList[rr.AreaId].AreaName;
                    dto.AreaId = rr.AreaId;
                    dto.RegionId = rr.RegionId;
                    dto.RegionName = CommonHelper.RegionsList[rr.RegionId].RegionName;
                    dto.MarketId = MarketId;
                    if (CommonHelper.MarketList[rr.MarketId].MarketKind != null) {
                        dto.MarketKindName = CommonHelper.MarketList[rr.MarketId].MarketKind.MarketKindName;
                    }
                    cachedData.Add(MarketId, dto);
                }
                dto = cachedData[MarketId];
                ProductKindData productKindData = new ProductKindData();
                if (!dto.DicProductKinds.ContainsKey(rr.ProductKindId)) {
                    productKindData.ProductKindName = ProductKindName;
                    productKindData.ProductLineName = pl.ProductLineName;
                    dto.DicProductKinds.Add(rr.ProductKindId, productKindData);
                } else {
                    productKindData = dto.DicProductKinds[rr.ProductKindId];
                }
                productKindData.ImportInventory += rr.StoreAmount;
                productKindData.SaleRate += rr.SaleRate;
                productKindData.DicProducts.Add(rr.ProductId, BuildProductData(rr));
            }
            List<MarketData> rs = new List<MarketData>();
            foreach (MarketData m in cachedData.Values) {
                ComputeAllProductKinds(pl, isAllocated, marketTo, marketFrom, m);
                rs.Add(m);
            }
            return rs;
        }

        public static ProductData BuildProductData(MarketProductImport rr) {
            ProductData p = new ProductData();
            p.ProductId = rr.ProductId;
            p.ProductCode = CommonHelper.ProductList[rr.ProductId].ProductCode;
            p.ProductName = CommonHelper.ProductList[rr.ProductId].ProductName;
            p.SaleRate = rr.SaleRate;
            p.ImportInventory = rr.StoreAmount;
            p.ComputedInventory = p.ImportInventory;
            p.ProductLineName = CommonHelper.CurrentProductLine.ProductLineName;
            return p;
        }

        private static void ComputeAllProductKinds(ProductLine pl, bool isAllocated,
            Dictionary<int, Dictionary<int, int>> marketTo, Dictionary<int, Dictionary<int, int>> marketFrom, MarketData m) {
            foreach (var pd in m.DicProductKinds) {
                int productKindId = pd.Key;
                int marketId = m.MarketId;
                ProductKindData p = pd.Value;
                int Package = pl.Package;
                int StableSellDays = pl.StableSellDays;
                int recomputeAmount = p.ImportInventory;
                if (isAllocated) {
                    // update data when transport before allocation
                    if (marketTo.ContainsKey(marketId) && marketTo[marketId].ContainsKey(productKindId)) {
                        recomputeAmount += marketTo[marketId][productKindId];
                    }
                    if (marketFrom.ContainsKey(marketId) && marketFrom[marketId].ContainsKey(productKindId)) {
                        recomputeAmount -= marketFrom[marketId][productKindId];
                    }
                    int temp = ComputedNeedProduct(p.SaleRate, recomputeAmount, StableSellDays);
                    p.ComputedStableProducts = Convert.ToInt32(temp / (double)Package + 0.5) * Package;
                } else {
                    int MinSellDays = pl.MinSellDays;
                    int MaxSellDays = pl.MaxSellDays;
                    p.ComputedMinProducts = ComputedNeedProduct(p.SaleRate, recomputeAmount, MinSellDays) + 1; // need round up
                    p.ComputedMaxProducts = ComputedNeedProduct(p.SaleRate, recomputeAmount, MaxSellDays);
                }

            }
        }
    }
}
